package com.hu.bgp.client.widgets.uicomponents;

import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.Widget;

/**
 * This abstract class is the base for any single selection (Radio button) table
 * To create your own Single Selection Table extends this class and provide the
 * header and creating methods based on T
 * 
 * @author mklijn
 * @param <T>
 *            Is the type of the DTO the implementing SingleSelectionTable is
 *            displaying in its rows
 */
public abstract class SelectionTable<T> extends HeaderedFlexTable
{
	private static final String GAMETYPE_RADIOGROUP = "SelectionTable";
	private int rows = 1;
	private int columns = 1;
	private T selection;

	public SelectionTable() {
		super();
		clear();
		this.getElement().addClassName("selectiontable");
	}

	public T getSelection()
	{
		return selection;
	}

	public void addGameRow(T gameType)
	{
		new GameRow(gameType, createRow(gameType));
	}

	public void clear()
	{
		super.clear();
		rows = 1;
		columns = 1;
		this.setHeaderElement(0, DOM.createDiv());
		for (Label l : createHeader()) {
			this.setHeaderElement(columns++, l.getElement());
		}
	}

	/**
	 * Lets the implementing class specify the which elements are added for each
	 * row
	 * 
	 * @param rowData
	 *            is a simple DTO which widget and headers will be based on
	 * @return return all widget for the newly created row
	 */
	public abstract Widget[] createRow(T rowData);

	public abstract Label[] createHeader();

	protected class GameRow
	{
		private final T gameType;
		private final RadioButton rb = new RadioButton(GAMETYPE_RADIOGROUP);

		public GameRow(T gameType, Widget[] fields) {
			this.gameType = gameType;
			rb.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
				public void onValueChange(ValueChangeEvent<Boolean> event)
				{
					selection = GameRow.this.gameType;
				}
			});

			setWidget(rows, 0, rb);
			int rc = 1;
			for (Widget w : fields) {
				setWidget(rows, rc++, w);
			}
			rows++;
		}
	}
}
